package com.tx.trtccloud.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.trtc.v20190722.TrtcClient;
import com.tencentcloudapi.trtc.v20190722.models.*;
import com.tx.trtccloud.trtctool.token.GenerateTestUserSig;
import org.junit.jupiter.api.Test;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class CloudRecordService {
    // 通用参数
    static final String SECRET_ID = "SECRET_ID";
    static final String SECRET_KEY = "SECRET_KEY";

    static final String BUCKET_SECRET_ID = "BUCKET_SECRET_ID";
    static final String BUCKET_SECRET_KEY= "BUCKET_SECRET_KEY";

    static final Long SDK_APP_ID = SDK_APP_ID;
    // 传入参数
    static String roomId = "911";
    // 停止参数，需手动更新
    static String stopTaskId = "";
    static Long stopTaskTime = 5 * 1000L; // 接口调用间隔时间

    public static void main(String[] args) {

        try {
            startRecordInner(null);
            System.out.println("开始录制后，验证状态 " + stopTaskTime + "ms");
            Thread.sleep(stopTaskTime);
            queryRecordingStateInner(null);
            System.out.println("停止录制" + stopTaskTime + "ms");
            Thread.sleep(stopTaskTime);
            stopRecordInner(null);
            System.out.println("停止录制后，验证状态 " + stopTaskTime + "ms");
            Thread.sleep(stopTaskTime);
            queryRecordingStateInner(null);

        }
        catch (Exception e) {
            System.out.println(e.toString());
        }
    }

    @Test // 开启主流录制
    public void bosuoStartCameraRecord() throws Exception {
        // mediaId 0 表示主流 1 表示辅流
        String cameraStreamParas = "{\n" +
                "\t\"audioUserIds\": [\"student\"],\n" +
                "\t\"videoUserIds\": [\"teacher\"],\n" +
                "\t\"mixLayoutList\": [{\n" +
                "\t\t\"userId\": \"teacher\",\n" +
                "\t\t\"mediaId\": 0\n" +
                "\t}]\n" +
                "}";
        JSONObject json = JSONObject.parseObject(cameraStreamParas);
        String results = startRecordInner(json);
        Thread.sleep(40 * 1000);
        String taskId = JSONObject.parseObject(results).getString("TaskId");
        queryRecordingStateInner(taskId);
        Thread.sleep(5000);
        stopRecordInner(taskId);
    }

    @Test // 开启辅流录制
    public void bosuoStartScreenCaptureRecord() throws Exception  {
        // mediaId 0 表示主流 1 表示辅流
        String cameraStreamParas = "{\n" +
                "\t\"audioUserIds\": [\"teacher\"],\n" +
                "\t\"videoUserIds\": [\"teacher\"],\n" +
                "\t\"mixLayoutList\": [{\n" +
                "\t\t\"userId\": \"teacher\",\n" +
                "\t\t\"mediaId\": 1\n" +
                "\t}]\n" +
                "}";
        JSONObject json = JSONObject.parseObject(cameraStreamParas);
        String results = startRecordInner(json);
        Thread.sleep(20 * 1000);
        String taskId = JSONObject.parseObject(results).getString("TaskId");
        queryRecordingStateInner(taskId);
        stopRecordInner(taskId);
    }

    public String  startRecord(JSONObject obj) {
        return startRecordInner(obj);
    }

    public String stopRecord(JSONObject obj) {
        return stopRecordInner(obj.getString("taskId"));
    }

    public String queryRecordingState(JSONObject obj) {
        return queryRecordingStateInner(obj.getString("taskId"));
    }

    public String updateLayout(JSONObject obj) {
        return updateLayoutInner(obj);
    }

    static String startRecordInner(JSONObject obj) {

        String results = null;

        TrtcClient client = getClient();
        // 实例化一个请求对象,每个接口都会对应一个request对象
        CreateCloudRecordingRequest req = new CreateCloudRecordingRequest();
        req.setSdkAppId(SDK_APP_ID);
        req.setRoomId(roomId);
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        req.setUserId(roomId + "_record" + uuid);
        req.setUserSig(GenerateTestUserSig.genTestUserSig(req.getUserId()));

        RecordParams recordParams = new RecordParams();
        recordParams.setRecordMode(2L);
        recordParams.setMaxIdleTime(5L);
        recordParams.setStreamType(0L);

        SubscribeStreamUserIds ids = new SubscribeStreamUserIds();
        String[] subscribeVideoIds = {"1"};
        String[] subscribeAudioIds = {"1"};
        String[] unSubscribeVideoIds = {"3"};
        String[] unSubscribeAudioIds = {"3"};
        ids.setSubscribeVideoUserIds(subscribeVideoIds);
        ids.setSubscribeAudioUserIds(subscribeAudioIds);
//        ids.setUnSubscribeVideoUserIds(unSubscribeVideoIds);
//        ids.setUnSubscribeAudioUserIds(unSubscribeAudioIds);
        recordParams.setSubscribeStreamUserIds(ids);
        req.setRecordParams(recordParams);

        // accesskey、secretkey	密钥信息，分别替换为用户的 SecretId 和 SecretKey
        StorageParams storageParams = new StorageParams();
        CloudStorage cloudStorage = new CloudStorage();
        cloudStorage.setVendor(0L);
        cloudStorage.setRegion("ap-shanghai");
//        "Bucket": "trtc-records-1300172876",
//                "AccessKey": "AKIDtc4FAoBH6ewxhANIxLSIr9BvOaWBZgW6",
//                "SecretKey": "KN9fusYx5wWpse9NL2SbS4PTGm1zg7H5",
//                "FileNamePrefix": ["exttmp", "test", "11091641611406003ttestconfgo1", "t1"]
        cloudStorage.setBucket("ryker-1300221102");
        cloudStorage.setAccessKey(BUCKET_SECRET_ID);
        cloudStorage.setSecretKey(BUCKET_SECRET_KEY);
        String[] prefixs = {"trtcRecord", getNowDateString()};
        cloudStorage.setFileNamePrefix(prefixs);
        storageParams.setCloudStorage(cloudStorage);
        req.setStorageParams(storageParams);

        /* *********** 非必须参数 ************** */

        req.setRoomIdType(1L);
        // 设置混流参数
        MixTranscodeParams mixTransParams = new MixTranscodeParams();
        VideoParams videoParams = new VideoParams();
        videoParams.setBitRate(64000L);
        videoParams.setFps(15L);
        videoParams.setGop(2L);
        videoParams.setWidth(630L);
        videoParams.setHeight(360L);
        mixTransParams.setVideoParams(videoParams);
        AudioParams audioParams  = new AudioParams();
        audioParams.setChannel(2L);
        audioParams.setSampleRate(1L);
        audioParams.setBitRate(32000L);
        mixTransParams.setAudioParams(audioParams);
        req.setMixTranscodeParams(mixTransParams);
        // 混流布局
        MixLayoutParams mixLayoutParams = new MixLayoutParams();
        mixLayoutParams.setMixLayoutMode(4L);
        mixLayoutParams.setBackGroundColor("#000000");
        mixLayoutParams.setMaxResolutionUserId("1");
        mixLayoutParams.setMediaId(0L);
        MixLayout mixLayout = new MixLayout();
        mixLayout.setTop(0L);
        mixLayout.setLeft(0L);
        mixLayout.setWidth(630L);
        mixLayout.setHeight(360L);
        mixLayout.setUserId("1");
        mixLayout.setRenderMode(2L);
        mixLayout.setMediaId(0L);
        MixLayout[] mixLayouts = { mixLayout };
        mixLayoutParams.setMixLayoutList(mixLayouts);
        req.setMixLayoutParams(mixLayoutParams);


        // 上面是测试数据，如果有接口数据将在下面赋值
        String[] audioIds = getAudioIds(obj);
        String[] videoIds = getVideoIds(obj);
        MixLayout[] mixs = getLayouts(obj);
        if (audioIds != null) {
            ids.setSubscribeAudioUserIds(audioIds);
        }
        if (videoIds != null) {
            ids.setSubscribeVideoUserIds(videoIds);
        }
        if (mixs != null) {
            mixLayoutParams.setMixLayoutList(mixs);
        }


        try {
            // 返回的resp是一个StartMCUMixTranscodeResponse的实例，与请求对象对应
            CreateCloudRecordingResponse resp = client.CreateCloudRecording(req);
            // 输出json格式的字符串回包
            results = CreateCloudRecordingResponse.toJsonString(resp);
            System.out.println(results);
            stopTaskId = resp.getTaskId();
        }
        catch (Exception e) {
            System.out.println(e.toString());
        }
        return results;
    }

    static String queryRecordingStateInner(String taskId) {
        String results = null;
        try {
            TrtcClient client = getClient();

            DescribeCloudRecordingRequest req = new DescribeCloudRecordingRequest();
            req.setTaskId(stopTaskId);
            if (taskId != null) {
                req.setTaskId(taskId);
            }
            req.setSdkAppId(SDK_APP_ID);
            // 返回的resp是一个StartMCUMixTranscodeResponse的实例，与请求对象对应
            DescribeCloudRecordingResponse resp = client.DescribeCloudRecording(req);
            // 输出json格式的字符串回包
            results = DescribeCloudRecordingResponse.toJsonString(resp);
            System.out.println(results);
        }
        catch (Exception e) {
            System.out.println(e.toString());
        }
        return results;
    }

    static String stopRecordInner(String taskId) {
        String results = null;
        try {
            TrtcClient client = getClient();
            DeleteCloudRecordingRequest req = new DeleteCloudRecordingRequest();
            req.setTaskId(stopTaskId);
            if (taskId != null) {
                req.setTaskId(taskId);
            }
            req.setSdkAppId(SDK_APP_ID);
            // 返回的resp是一个StartMCUMixTranscodeResponse的实例，与请求对象对应
            DeleteCloudRecordingResponse resp = client.DeleteCloudRecording(req);
            // 输出json格式的字符串回包
            results = DeleteCloudRecordingResponse.toJsonString(resp);
            System.out.println(results);
        }
        catch (Exception e) {
            System.out.println(e.toString());
        }
        return results;
    }

    static String updateLayoutInner(JSONObject obj) {
        String results = null;
        try {
            TrtcClient client = getClient();
            ModifyCloudRecordingRequest req = new ModifyCloudRecordingRequest();
            req.setTaskId(stopTaskId);
            req.setSdkAppId(SDK_APP_ID);
            // 返回的resp是一个StartMCUMixTranscodeResponse的实例，与请求对象对应
            ModifyCloudRecordingResponse resp = client.ModifyCloudRecording(req);
            // 输出json格式的字符串回包
            results = ModifyCloudRecordingResponse.toJsonString(resp);
            System.out.println(results);
        }
        catch (Exception e) {
            System.out.println(e.toString());
        }
        return results;
    }

    private static TrtcClient getClient() {
        Credential cred = new Credential(SECRET_ID, SECRET_KEY);
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("trtc.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        TrtcClient client = new TrtcClient(cred, "ap-shanghai", clientProfile);
        return client;
    }

    private static String[] getAudioIds(JSONObject obj) {
        if (obj != null) {
            List<String> audioUserIds = obj.getJSONArray("audioUserIds").toJavaList(String.class);
            if (audioUserIds.size() == 0) {
                return null;
            }
            String[] s = new String[audioUserIds.size()];
            return audioUserIds.toArray(s);
        }
        return null;
    }

    private static String[] getVideoIds(JSONObject obj) {
        if (obj != null) {
            List<String> videoUserIds = obj.getJSONArray("videoUserIds").toJavaList(String.class);
            if (videoUserIds.size() == 0) {
                return null;
            }
            String[] s = new String[videoUserIds.size()];
            return videoUserIds.toArray(s);
        }
        return null;
    }

    private static MixLayout[] getLayouts(JSONObject obj) {
        if (obj != null) {
            List<MixLayout> mixLayouts = new ArrayList<>();
            // 视频需要考虑混流布局，大小流、填充等信息
            JSONArray mixLayoutList = obj.getJSONArray("mixLayoutList");
            if (mixLayoutList.size() == 0) {
                return null;
            }
            for (int i=0; i < mixLayoutList.size(); i++) {
                JSONObject mixLayoutDesc = mixLayoutList.getJSONObject(i);
                MixLayout mixLayout = new MixLayout();
                mixLayout.setTop(0L);
                mixLayout.setLeft(0L);
                mixLayout.setWidth(630L);
                mixLayout.setHeight(360L);
                mixLayout.setRenderMode(2L);
                mixLayout.setMediaId(0L);
                mixLayout.setUserId(mixLayoutDesc.getString("userId"));
                if (mixLayoutDesc.getLong("mediaId") != null) {
                    mixLayout.setMediaId(mixLayoutDesc.getLong("mediaId"));
                }
                mixLayouts.add(mixLayout);
            }
            MixLayout[] rtMixLayouts = new MixLayout[mixLayouts.size()];
            return mixLayouts.toArray(rtMixLayouts);
        }
        return null;
    }

    static String getNowDateString() {
        Date date = new Date();//获取当前的日期
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
        String str = df.format(date);//获取String类型的时间
        System.out.println(str);
//        str = str.replace(" ", "__").replace(":", "_").replace("-");
        return str;
    }
}
